/*
 * PaintPicker.java
 *
 * Created on July 19, 2006, 7:13 PM
 */

package org.jdesktop.beans.editors;

import java.awt.Color;
import java.awt.Component;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jdesktop.swingx.JXGradientChooser;
import org.jdesktop.swingx.color.EyeDropperColorChooserPanel;
import org.jdesktop.swingx.util.PaintUtils;

/**
 *
 * @author joshy
 */
public class PaintPicker extends javax.swing.JPanel {
	Component lastPickerUsed = null;
	Paint selectedPaint = Color.PINK;
	JXGradientChooser gradientPicker;

	/** Creates new form PaintPicker */
	public PaintPicker() {
		initComponents();

		// set up the color picker
		lastPickerUsed = colorPicker;
		colorPicker.addChooserPanel(new EyeDropperColorChooserPanel());
		ColorListener colorListener = new ColorListener();
		colorPicker.getSelectionModel().addChangeListener(colorListener);
		alphaSlider.addChangeListener(colorListener);

		// set up the gradient picker
		gradientPicker = new JXGradientChooser();
		tabbedPane.addTab("Gradient", gradientPicker);
		gradientPicker.addPropertyChangeListener("gradient", new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
				lastPickerUsed = gradientPicker;
				setPaint(gradientPicker.getGradient());
			}
		});

		// update when the tabs change
		tabbedPane.getModel().addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent changeEvent) {
				lastPickerUsed = tabbedPane.getSelectedComponent();
				Paint old = selectedPaint;
				if (lastPickerUsed == colorPickerParent) {
					selectedPaint = colorPicker.getSelectionModel().getSelectedColor();
				}
				if (lastPickerUsed == gradientPicker) {
					selectedPaint = gradientPicker.getGradient();
				}
				firePropertyChange("paint", old, selectedPaint);
			}
		});

	}

	public Paint getPaint() {
		return selectedPaint;
	}

	public void addPicker(JComponent comp, String title) {
		tabbedPane.addTab(title, comp);
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// desc=" Generated Code ">//GEN-BEGIN:initComponents
	private void initComponents() {
		java.awt.GridBagConstraints gridBagConstraints;

		tabbedPane = new javax.swing.JTabbedPane();
		colorPickerParent = new javax.swing.JPanel();
		colorPicker = new javax.swing.JColorChooser();
		jLabel1 = new javax.swing.JLabel();
		alphaSlider = new javax.swing.JSlider();

		setLayout(new java.awt.GridBagLayout());

		colorPickerParent.setLayout(new java.awt.GridBagLayout());

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.weightx = 10.0;
		gridBagConstraints.weighty = 10.0;
		colorPickerParent.add(colorPicker, gridBagConstraints);

		jLabel1.setText("Alpha:");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		colorPickerParent.add(jLabel1, gridBagConstraints);

		alphaSlider.setMaximum(255);
		alphaSlider.setValue(255);
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		colorPickerParent.add(alphaSlider, gridBagConstraints);

		tabbedPane.addTab("Color", colorPickerParent);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 10.0;
		gridBagConstraints.weighty = 10.0;
		add(tabbedPane, gridBagConstraints);

	}// </editor-fold>//GEN-END:initComponents

	public void setPaint(Paint paint) {
		if (paint == selectedPaint) {
			return;
		}
		Paint old = selectedPaint;
		selectedPaint = paint;
		if (paint instanceof Color) {
			tabbedPane.setSelectedComponent(colorPickerParent);
			colorPicker.setColor((Color) paint);
			alphaSlider.setValue(((Color) paint).getAlpha());
		}
		if (paint instanceof MultipleGradientPaint) {
			tabbedPane.setSelectedComponent(gradientPicker);
			gradientPicker.setGradient((MultipleGradientPaint) paint);
		}
		firePropertyChange("paint", old, selectedPaint);
	}

	// return a paint suitable for display in a property sheet preview
	Paint getDisplayPaint(Rectangle box) {
		if (getPaint() instanceof MultipleGradientPaint) {
			return getFlatGradient(gradientPicker, box.getWidth());
		}
		return getPaint();
	}

	/**
	 * Creates a flat version of the current gradient. This is a linear gradient
	 * from 0.0 to length,0. This gradient is suitable for drawing previews of
	 * the real gradient.
	 *
	 * @param length
	 * @return a gradient Paint with values between 0.0 and length
	 */
	private MultipleGradientPaint getFlatGradient(JXGradientChooser chooser, double length) {
		MultipleGradientPaint gp = chooser.getGradient();

		// set up the data for the gradient
		float[] fractions = gp.getFractions();
		Color[] colors = gp.getColors();

		// fill in the gradient
		Point2D start = new Point2D.Float(0, 0);
		Point2D end = new Point2D.Float((float) length, 0);
		MultipleGradientPaint paint = new LinearGradientPaint((float) start.getX(), (float) start.getY(), (float) end.getX(),
				(float) end.getY(), fractions, colors);
		return paint;
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JSlider alphaSlider;
	public javax.swing.JColorChooser colorPicker;
	private javax.swing.JPanel colorPickerParent;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JTabbedPane tabbedPane;

	// End of variables declaration//GEN-END:variables

	private class ColorListener implements ChangeListener {
		public void stateChanged(ChangeEvent e) {
			lastPickerUsed = colorPicker;
			Paint old = selectedPaint;
			selectedPaint = PaintUtils.setAlpha(colorPicker.getSelectionModel().getSelectedColor(), alphaSlider.getValue());
			firePropertyChange("paint", old, selectedPaint);
		}
	}

}
